home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c++-part2 / 17984 < prev    next >
Encoding:
Text File  |  1996-08-05  |  2.3 KB  |  94 lines

  1. Path: mumrik.nada.kth.se!d92-foh
  2. From: Fredrik ╓hrstr÷m <d92-foh@nada.kth.se>
  3. Newsgroups: comp.lang.c++
  4. Subject: Here is my idea of callback code. However there are glitches can it be done better.
  5. Date: Thu, 18 Apr 1996 13:02:45 +0200
  6. Message-ID: <Pine.SUN.3.91N2x.960418124921.4515B-100000@mumrik.nada.kth.se>
  7. NNTP-Posting-Host: mumrik.nada.kth.se
  8. Mime-Version: 1.0
  9. Content-Type: TEXT/PLAIN; charset=US-ASCII
  10.  
  11.  
  12. How do people write callbacks? The following code captures what I want 
  13. of callbacks. 
  14. * Callbacks call class functions. 
  15. * The calling object does not need to know what object, what function, 
  16.   what callback it is calling. It knows that it calls a TutCallback f.ex.
  17.   but if the user wants to subclass the TutCallback to insert more 
  18.   information at callback time thats completely ok. 
  19. * It is easy to create new callbacks. (Before I hade to create two classes
  20.   for each new callback.)
  21. However there are some negative things.
  22. * It is a pointer to pointer to function thingi.
  23. * The compiler warns >>Contravariance violation<<
  24.   Because I cast b = void (Test::*)(TutCallback*) 
  25.           to void (Test::*)(Callback*)
  26.   And I do not know how to stop this from happening.
  27.  
  28.   Is there anyone out there that has a better way of calling callbacks?
  29.   Or if somebody knows how to fix this I would be very happy!
  30.  
  31. Here's the code. (Just the essential stuff, no memchecking and so on.)
  32.  
  33. #include <iostream.h>
  34.  
  35. struct Caller;
  36. template<class T> struct Call;
  37. struct Callback;
  38.  
  39. struct Caller
  40. {
  41.   virtual void call (Callback *cb) { }
  42. };
  43.  
  44. template<class T>
  45. struct Call : public Caller
  46. {
  47.   typedef void (T::*FuncPtr)(Callback *);
  48.   
  49.   Call (T *o, FuncPtr f) : object_(o), function_(FuncPtr(f)) { }
  50.  
  51.   void call (Callback *cb) { (object_->*function_) (cb); }
  52.  
  53.   T *object_;
  54.   FuncPtr function_;
  55. };
  56.  
  57. struct Callback
  58. {
  59.   Callback (Caller *caller) : caller_ (caller) { }
  60.   virtual void invoke () { caller_->call (this); }
  61.   
  62.   Caller *caller_;
  63. };
  64.  
  65. // This is an easy way to create new Callbacks I think!
  66.  
  67. struct TutCallback : public Callback
  68. {
  69.   TutCallback (Caller *c, int u) : Callback (c), tut (u) { }
  70.  
  71.   int tut;
  72. };
  73.  
  74. struct Test
  75. {
  76.   TutCallback *cb;
  77.  
  78.   Test ()
  79.   {
  80.     cb = new TutCallback (new Call<Test>(this,b), 5);
  81.     cb->invoke ();
  82.   }
  83.  
  84.   void b (TutCallback *cb)
  85.   {
  86.     cerr << "Tut! " << cb->tut << endl;
  87.   }
  88. };
  89.  
  90. int main ()
  91. {
  92.   Test test;
  93. }
  94.